/**
 * Defines a generic class for items.
 * Fields are already encoded.
 * 
 * @author remo.lemma@lu.unisi.ch and patrick.zulian@lu.unisi.ch
 */

package ch.unisi.inf.projects.java.uom.elements;

// Libraries
import java.util.Map;
import java.util.HashMap;

import ch.unisi.inf.projects.java.uom.Constants;
import ch.unisi.inf.projects.java.uom.ConstantArrays;
import ch.unisi.inf.projects.java.uom.Pair;
import ch.unisi.inf.projects.java.uom.Database;

public class ItemClass extends Element {
	
	/**
	 * Constructor that should be used only when data are loaded
	 * @param name the name of the ItemClass
	 * @param fields the fields of the class
	 * @param modified if the class has been modified
	 */
	public ItemClass (final String name, final Map<String,String> fields, final boolean modified)
	{
		super(name, fields, modified);
		// Primary Key is always present
		this.getFields().put(Constants.ITEM_PRIMARY_KEY.value(),null);
		for (final String field : ConstantArrays.ITEM_COMMON_FIELDS.value())
			this.getFields().put(field, null);
	}
	
	/**
	 * Constructor for a new ItemClass without any field
	 * @param name the name of the ItemClass
	 */
	public ItemClass (final String name)
	{
		this(name, new HashMap<String,String>(), true);
	}
	
	/**
	 * Checks if the given field is one of the protected fields
	 * @param field the name of the field
	 * @return true if the field is protected
	 */
	private boolean isProtected (final String field)
	{
		return (field.equals(Constants.ITEM_PRIMARY_KEY.value()) || ConstantArrays.ITEM_COMMON_FIELDS.contains(field));
	}
	
	/**
	 * Removes a fields
	 * @param field the field to be removed
	 */
	public void removeField (final String field)
	{
		if (field == null || isProtected(field) || !getFields().keySet().contains(field.toUpperCase()))
			return;
		getFields().remove(field.toUpperCase());
		getUpdates().add(new Pair<String,String>(field.toUpperCase(),null));
		setModified(true);
	}
	
	/**
	 * Modifies the name of a field
	 * @param field the field's name
	 * @param newField the new field's name
	 */
	public void setField (final String field, final String newField)
	{
		if (field == null || newField == null || !getFields().keySet().contains(field.toUpperCase()))
			return;
		getFields().remove(field.toUpperCase());
		getFields().put(newField.toUpperCase(),null);
		getUpdates().add(new Pair<String,String>(field.toUpperCase(), newField.toUpperCase()));
		setModified(true);
	}
	
	/**
	 * Saves the ItemClass in the database (add or update)
	 * @throws Exception handles the needed exceptions
	 */
	public void save() throws Exception
	{
		Database.instance().itemClassSave(this);
	}
	
	/**
	 * Deletes the ItemClass from the database
	 * @throws Exception handles the needed exceptions
	 */
	public void delete() throws Exception
	{
		Database.instance().itemClassDelete(this);
	}
}